<?php
// $Id$

/**
 * @file
 */

/**
 * Menu callback; Present an administrative raid listing.
 */
function guild_admin_raid_page() {
  $edit = $_POST;
  
  if (isset($edit['operation']) && ($edit['operation'] == 'delete') && isset($edit['raids']) && $edit['raids']) {
    module_load_include('inc', 'guild', 'includes/guild.admin');
    return drupal_get_form('guild_operation_multiple_delete_confirm');
  }
  
  return drupal_get_form('guild_raid_overview');
}

/**
 * Form builder; Raid editing page.
 *
 * @param $op The editing operation, either 'add' or 'edit'.
 * @param $raid (optional) If supplied by the menu loader, contains an array
 *   with raid values.
 */
function guild_raid_edit($form_state, $op, $raid = NULL) {
  module_load_include('inc', 'guild', 'includes/guild.standings');
  
  if (empty($raid) || $op == 'add') {
    $raid = array(
      'raid_id'    => NULL,
      'name'       => '',
      'comment'    => '',
      'timestamp'  => time(),
      'listing_id' => 0
    );
  }
  //else {
  //  // @todo Should the time portion ever be used, change the format to match drupal settings.
  //  $t_args = array('@name' => $raid['name'], '@date' => format_date($raid['timestamp'], 'custom', 'F j, Y'));
  //  drupal_set_title(t('Raid: @name on @date', $t_args));
  //}
  
  $standings_picker = guild_standings_picker();
  if ($standings_picker['#default_value'] == '') {
    $t_args = array('@add-listing' => url('admin/guild/standings/add', array('query' => drupal_get_destination())));
    drupal_set_message(t('You must <a href="@add-listing">create a listing</a> before raids can be added to it.', $t_args), 'error');
    drupal_goto('admin/guild/raids');
  }
  
  $form['raid_op'] = array('#type' => 'value', '#value' => $op);
  $form['raid_id'] = array('#type' => 'value', '#value' => $raid['raid_id']);
  
  $form['date'] = array(
    '#type' => 'guild_date',
    '#title' => t('Raid date'),
    '#default_value' => $raid['timestamp'],
    '#required' => TRUE,
    '#tree' => TRUE
  );
  
  //$form['time'] = array(
  //  '#type' => 'item',
  //  '#title' => t('Raid time'),
  //  '#description' => t('The time of day, using 24-hour notation.'),
  //  '#tree' => TRUE
  //);
  
  //$form['time']['hour'] = array(
  //  '#type' => 'textfield',
  //  '#default_value' => '00',
  //  '#maxlength' => 2,
  //  '#size' => 2,
  //  '#prefix' => '<div class="container-inline">'
  //);
  
  // Not normally included in written 24-hour notation.
  //$form['time']['colon'] = array(
  //  '#value' => ':'
  //);
  
  //$form['time']['minute'] = array(
  //  '#type' => 'textfield',
  //  '#default_value' => '00',
  //  '#maxlength' => 2,
  //  '#size' => 2,
  //  '#suffix' => '</div>'
  //);
  
  // @todo Modify according to hook_guild_game() -- if this capability gets implemented.
  $form['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Raid name'),
    '#default_value' => $raid['name'],
    '#maxlength' => 64,
    '#required' => TRUE
  );
  
  $form['comment'] = array(
    '#type' => 'textarea',
    '#title' => t('Raid comment'),
    '#default_value' => $raid['comment'],
    '#rows' => 2
  );
  
  $form['listing_id'] = $standings_picker;
  $form['listing_id']['#description'] = 'This field determines which listing this raid will belong to, and consequently, how the values of events and items added to the raid are calculated. ' .
    '<strong>' . t('Warning: This field cannot be changed after the raid has been created.') . '</strong>';
  if ($op == 'edit') {
    $form['listing_id']['#disabled'] = TRUE;
    $form['listing_id']['#default_value'] = $raid['listing_id'];
    unset($form['listing_id']['#description']);
  }
  
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => ($op == 'edit') ? t('Update') : t('Create')
  );
  
  if ($op == 'add') {
    $form['add_events'] = array('#type' => 'submit', '#value' => t('Add events'));
  }
  
  return $form;
}

/**
 * Validate an editied raid form.
 *
 */
function guild_raid_edit_validate($form, &$form_state) {
  $values = $form_state['values'];
  
  // @todo Warn the user if date is in the future?
}

/**
 * Process and log an edited raid form.
 */
function guild_raid_edit_submit($form, &$form_state) {
  $values = $form_state['values'];
  
  // Unix timestamps have no timezone, and are inherently UTC time, so if we
  // used mktime() it would be adjusted to the server's time instead of being
  // kept at UTC.
  $timestamp = gmmktime(0, 0, 0, $values['date']['month'], $values['date']['day'], $values['date']['year']);
  
  // However, the time entered was meant to be in the user's timezone, so we
  // still need to convert to actual UTC time before saving.
  $form_state['values']['timestamp'] = guild_timezone_to_utc($timestamp);
  guild_save_raid($form_state['values']);
  
  $t_args = array('%name' => $values['name'], '%date' => format_date($form_state['values']['timestamp'], 'custom', 'F j, Y'));
  if ($values['raid_op'] == 'add') {
    drupal_set_message(t('The raid %name on %date has been created.', $t_args));
  }
  else {
    drupal_set_message(t('The raid %name on %date has been updated.', $t_args));
  }
  
  if ($values['op'] == t('Add events')) {
    $raid_id = $form_state['values']['raid_id'];
    $form_state['redirect'] = 'admin/guild/raids/' . $raid_id . '/events/add';
  }
  else {
    $form_state['redirect'] = 'admin/guild/raids';
  }
}

/**
 *
 *
 * @param array $edit
 *   An associative array describing the raid and the operation to perform. If
 *   a raid is being inserted into the database, the primary key field will also
 *   be updated.
 */
function guild_save_raid(&$edit) {
  $t_args = array('%name' => $edit['name'], '%date' => format_date($edit['timestamp'], 'custom', 'F j, Y'));
  
  if ($edit['raid_op'] == 'add') {
    drupal_write_record('guild_raid', $edit);
    watchdog('guild', 'raid: added %name (%date)', $t_args);
  }
  else if ($edit['raid_op'] == 'edit') {
    drupal_write_record('guild_raid', $edit, 'raid_id');
    watchdog('guild', 'raid: updated %name (%date)', $t_args);
  }
}

/**
 * Form builder; Generates a paged table form representing all raids.
 *
 * @param array $form_state
 *   This parameter is not used.
 *
 * @return array A form showing available raids in a table, with a pager when necessary.
 *
 * @see theme_guild_raid_overview()
 */
function guild_raid_overview(&$form_state) {
  module_load_include('inc', 'guild', 'includes/guild.admin');
  $form = guild_admin_operations('raids');
  
  // Setup the table header.
  $form['header'] = array(
    '#type' => 'value',
    '#value' => array(
      theme('table_select_header_cell'),
      array('data' => t('Date'), 'field' => 'timestamp', 'sort' => 'desc'),
      array('data' => t('Name'), 'field' => 'name'),
      array('data' => t('Listing'), 'field' => 'listing'),
      //array('data' => t('Members'), 'field' => 'members'),
      //array('data' => t('Events'), 'field' => 'events'),
      array('data' => t('Operations'), 'colspan' => 4)
    )
  );
  
  // Create the raid table.
  $count_query = "SELECT COUNT(raid_id) FROM {guild_raid} r";
  $raids_per_page = 50;
  
  $query = pager_query(
    "SELECT r.raid_id AS id, r.name, r.timestamp, l.title AS listing " .
  //"SELECT r.raid_id AS id, r.name, r.timestamp, l.title AS listing, COUNT(DISTINCT t.nid) AS members, COUNT(ei.event_instance_id) AS events " .
    "FROM {guild_raid} r " .
    "LEFT JOIN {guild_listing} l USING(listing_id) " .
  //"LEFT JOIN {guild_event_instance} ei USING(raid_id) " .
  //"LEFT JOIN {guild_transaction} t USING(event_instance_id) " .
  //"GROUP BY r.raid_id " .
    tablesort_sql($form['header']['#value']), $raids_per_page, 0, $count_query
  );
  
  while ($raid = db_fetch_object($query)) {
    $raids[$raid->id] = '';
    
    // @todo Localize date format.
    // @todo Should names be truncated to ~30 characters?
    $form['date'][$raid->id] = array('#value' => format_date($raid->timestamp, 'custom', 'm/d/Y')); // F j, Y
    $form['name'][$raid->id] = array('#value' => check_plain($raid->name));
    $form['listing'][$raid->id] = array('#value' => check_plain($raid->listing));
    //$form['member_count'][$raid->id] = array('#value' => $raid->members);
    //$form['event_count'][$raid->id] = array('#value' => $raid->events);
    
    // @todo Remove 'members' link when there are no events assigned to a raid.
    $form['edit'][$raid->id] = array('#value' => l(t('edit'), 'admin/guild/raids/' . $raid->id . '/edit'));
    $form['events'][$raid->id] = array('#value' => l(t('events'), 'admin/guild/raids/' . $raid->id . '/events'));
    $form['members'][$raid->id] = array('#value' => l(t('members'), 'admin/guild/raids/' . $raid->id . '/members'));
    $form['items'][$raid->id] = array('#value' => l(t('items'), 'admin/guild/raids/' . $raid->id . '/items'));
  }
  
  $form['raids'] = array(
    '#type' => 'checkboxes',
    '#options' => isset($raids) ? $raids : array()
  );
  $form['pager'] = array('#value' => theme('pager', NULL, $raids_per_page, 0));
  
  return $form;
}

/**
 *
 *
 * @ingroup themeable
 */
function theme_guild_raid_overview($form) {
  $output = drupal_render($form['update']);
  
  if (isset($form['date']) && is_array($form['date'])) {
    foreach (element_children($form['date']) as $key) {
      $row = array();
      $row[] = drupal_render($form['raids'][$key]);
      $row[] = drupal_render($form['date'][$key]);
      $row[] = drupal_render($form['name'][$key]);
      $row[] = drupal_render($form['listing'][$key]);
      //$row[] = drupal_render($form['member_count'][$key]);
      //$row[] = drupal_render($form['event_count'][$key]);
      $row[] = drupal_render($form['edit'][$key]);
      $row[] = drupal_render($form['events'][$key]);
      $row[] = drupal_render($form['members'][$key]);
      $row[] = drupal_render($form['items'][$key]);
      
      $rows[] = $row;
    }
  }
  else {
    $rows[] = array(array(
      'data' => t('No raids available.'),
      'colspan' => '8',
      'align' => 'center'
    ));
  }
  
  $output .= theme('table', $form['header']['#value'], $rows);
  if ($form['pager']['#value']) {
    $output .= drupal_render($form['pager']);
  }

  $output .= drupal_render($form);

  return $output;
}

/**
 * @todo Not used?
 */
function guild_raid_event_overview(&$form_state, $raid = NULL) {
  if (empty($raid)) {
    return drupal_not_found();
  }
  
  $form['header'] = array(
    '#type' => 'value',
    '#value' => array(
      array('data' => t('Event'), 'field' => 'name', 'sort' => 'asc'),
      array('data' => t('Value'), 'field' => 'amount'),
    //array('data' => t('Members')),
      array('data' => t('Operations'))
    )
  );
  
  $query = db_query(
    "SELECT ei.event_instance_id AS id, et.name, ev.amount, COUNT(t.nid) AS members " .
    "FROM {guild_event_instance} ei " .
    "INNER JOIN {guild_event_value} ev USING(event_value_id) " .
    "INNER JOIN {guild_event_template} et USING(event_template_id) " .
    "LEFT JOIN {guild_transaction} t USING(event_instance_id) " .
    "WHERE ei.raid_id = %d " .
    "GROUP BY et.event_template_id " .
    tablesort_sql($form['header']['#value']),
    $raid['raid_id']
  );
  
  // @todo Integrate with point systems.
  while ($event = db_fetch_object($query)) {
    $form['name'][$event->id] = array('#value' => check_plain($event->name));
    $form['amount'][$event->id] = array('#value' => $event->amount);
  //$form['members'][$event->id] = array('#value' => $event->members);
    $form['operations'][$event->id]  = array('#value' => l(t('remove'), 'admin/guild/raids/' . $raid['raid_id'] . '/events/' . $event->id . '/remove'));
  }
  
  return $form;
}

/**
 * 
 *
 * @ingroup themeable
 */
function theme_guild_raid_event_overview($form) {
  if (isset($form['name']) && is_array($form['name'])) {
    foreach (element_children($form['name']) as $key) {
      $row = array();
      $row[] = drupal_render($form['name'][$key]);
      $row[] = drupal_render($form['amount'][$key]);
    //$row[] = drupal_render($form['members'][$key]);
      $row[] = drupal_render($form['operations'][$key]);
      
      $rows[] = $row;
    }
  }
  else {
    $rows[] = array(array('data' => t('There are no events assigned to this raid.'), 'colspan' => '3', 'align' => 'center'));
  }
  
  $output = theme('table', $form['header']['#value'], $rows);
  
  $output .= drupal_render($form);
  return $output;
}

/**
 * @todo Even more experimental function than the one below.
 *
function guild_raid_event_edit(&$form_state, $raid = NULL) {
  if (empty($raid)) {
    return drupal_not_found();
  }
  
  $form['raid_id'] = array('#type' => 'value', '#value' => $raid['raid_id']);
  $form['listing_id'] = array('#type' => 'value', '#value' => $raid['listing_id']);
  
  $form['header'] = array(
    '#type' => 'value',
    '#value' => array(
      array('data' => t('Name'), 'field' => 'name', 'sort' => 'asc'),
      array('data' => t('Description')),
      array('data' => t('Value'))
    )
  );
  
  $form['add_event_name'] = array(
    '#type' => 'select',
    '#default_value' => 1,
    '#options' => array(1 => 'atramedes', 2 => 'nefarian', 3 => 'conclave of wind', 4 => 'heroic: maloriak', 5 => 'heroic: nefarian'),
    '#multiple' => FALSE,
  //'#size' => 35
  );
  
  $form['add_event_note'] = array(
    '#type' => 'textfield',
    '#default_value' => '',
    '#size' => 25
  );
  
  $form['add_event_value'] = array(
    '#type' => 'textfield',
    '#default_value' => 0,
    '#size' => 8
  );
  
  $form['add_event'] = array(
    '#type' => 'submit',
    '#value' => t('Add event')
  );
  
  $page_limit = 50;
  
  return $form;
}

function guild_raid_event_edit_validate($form, &$form_state) {
  dpm($form_state);
}
*/
/*
function theme_guild_raid_event_edit($form) {
  
  if (isset($form['name']) && is_array($form['name'])) {
    foreach (element_children($form['name']) as $key) {
      $name = drupal_render($form['name'][$key]);
      if (!empty($form['description'][$key]['#value'])) {
        $name .= '<div class="guild-description">' . drupal_render($form['description'][$key]) . "</div>\n";
      }
      
      $row = array();
      $row[] = drupal_render($form['events'][$key]);
      $row[] = $name;
      $row[] = drupal_render($form['note'][$key]);
      $row[] = drupal_render($form['amount'][$key]);
      
      $rows[] = $row;
    }
  }
  else {
    $t_args =  array('@add-events' => url('admin/guild/events/add', array('query' => drupal_get_destination())));
    $rows[] = array(array(
      'data' => t('No events available. You can create more at the <a href="@add-events">Guild management > Events</a> page.', $t_args),
      'colspan' => '4',
      'align' => 'center'
    ));
  }
  
  $rows[] = array(
    drupal_render($form['add_event_name']),
    drupal_render($form['add_event_note']),
    drupal_render($form['add_event_value']),
    array('data' => drupal_render($form['add_event']), 'colspan' => 2)
  );
  
  $output .= theme('table', $form['header']['#value'], $rows);
  if ($form['pager']['#value']) {
    $output .= drupal_render($form['pager']);
  }

  $output .= drupal_render($form);

  return $output;
}
*/
/**
 * @todo Experimental function: guild_raid_event_edit().
 *
 * @todo We could move the description under the event name and then add a
 *   textfield where the description was for per-instance notes?
 *
 * @todo Add a link the the raid members page.
 */

function guild_raid_event_edit(&$form_state, $raid = NULL) {
  if (empty($raid)) {
    return drupal_not_found();
  }
  
  $form['raid_id']       = array('#type' => 'value', '#value' => $raid['raid_id']);
  $form['listing_id']    = array('#type' => 'value', '#value' => $raid['listing_id']);
  
  // Output information used in theming this form.
  $form['raid_name']     = array('#value' => check_plain($raid['name']));
  $form['raid_comment']  = array('#value' => check_plain($raid['comment']));
  $form['raid_date']     = array('#value' => format_date($raid['timestamp'], 'small', '', 0));
  
  $form['header'] = array(
    '#type' => 'value',
    '#value' => array(
      theme('table_select_header_cell'),
      array('data' => t('Name'), 'field' => 'name', 'sort' => 'asc'),
      array('data' => t('Note')),
      array('data' => t('Value'))
    )
  );
  
  $events_per_page = 50;
  $query = pager_query(
    "SELECT et.event_template_id AS template_id, et.name, et.description, ev.event_value_id AS value_id, ev.amount, ei.raid_id " .
    "FROM {guild_event_template} et " .
    "LEFT JOIN {guild_event_value} ev ON et.event_template_id = ev.event_template_id AND ev.listing_id = %d " .
    "LEFT JOIN {guild_event_instance} ei USING(event_value_id) " .
    "WHERE et.type = '%s' " .
    tablesort_sql($form['header']['#value']), $events_per_page, 0, NULL,
    $raid['listing_id'], 'event'
  );
  $events = array();
  while ($event = db_fetch_object($query)) {
    // Skip events that have already been added to this raid.
    //if ($event->raid_id == $raid['raid_id']) {
    //  continue;
    //}
    $event_exists = ($event->raid_id == $raid['raid_id']);
    
    $events[$event->template_id] = '';
    
    //$form['events'][$event->template_id] = array('#type' => 'checkbox', '#default_value' => $event_exists);//, '#disabled' => $event_exists);
    
    $form['name'][$event->template_id] = array('#value' => check_plain($event->name));
    $form['description'][$event->template_id] = array('#value' => empty($event->description) ? '' : check_plain($event->description));
    $form['note'][$event->template_id] = array(
      '#type' => 'textfield',
      '#default_value' => '',
      '#size' => 30,
      '#maxlength' => 255,
      '#disabled' => $event_exists
    );
    
    // Store information from the {guild_event_value} table.
    $event_value_ids[$event->template_id] = is_null($event->value_id) ? 0 : $event->value_id;
    
    //if (!is_null($event->amount) && $listing['query_event'] == 'onEvent') {
      // @todo For manually entered values default to just '0', otherwise use '0.000'?
      $form['amount'][$event->template_id] = array(
        '#type' => 'textfield',
        '#default_value' => is_null($event->amount) ? '0' : intval($event->amount),
        '#size' => 9,
        '#maxlength' => 8,
        '#required' => TRUE,
        '#disabled' => $event_exists
      );
    //}
    //else {
    //  $form['amount'][$event->template_id] = array('#value' => is_null($event->amount) ? '--' : $event->amount);
    //}
  }
  
  $form['event_value_ids'] = array('#type' => 'value', '#value' => $event_value_ids);
  
  $form['events'] = array(
    '#type' => 'checkboxes',
    '#options' => isset($events) ? $events : array()
  );
  
  $form['addevents'] = array(
    '#type' => 'submit',
    '#value' => t('Add events')
  );
  
  return $form;
}

function guild_raid_event_edit_validate($form, &$form_state) {
  $form_state['values']['events'] = array_diff($form_state['values']['events'], array(0));
  
  if (count($form_state['values']['events']) == 0) {
    form_set_error('', t('You must select one or more events to add to this raid.'));
  }
  
  // @todo Check the note.
  dpm($form_state['values']);
  form_set_error('', 'testing');
  
  // @todo Check if the event value is within the domain of valid database storage values.
}

/**
 * 
 */
function guild_raid_event_edit_submit($form, &$form_state) {
  $values = $form_state['values'];
  
  foreach ($values['events'] as $template_id) {
    // In standard 'onEvent' point systems, the {guild_event_value} entry should
    // include the points to be awarded to each player. In 'onItem' point systems
    // this will simply be a place holder entry. The actual value will be
    // calculated and updated into the record later.
    
    $event_value = array(
      'event_template_id' => $template_id,
      'amount' => $values[$template_id],
      'listing_id' => $values['listing_id']
    );
    
    $value_id = $values['event_value_ids'][$template_id];
    if ($value_id == 0) {
      // Create new entry in {guild_event_value}.
      drupal_write_record('guild_event_value', $event_value);
    }
    else {
      // Update existing entry in {guild_event_value}.
      $event_value['event_value_id'] = $value_id;
      drupal_write_record('guild_event_value', $event_value, 'event_value_id');
      
      // @todo Send an alert to members of this event instance about the update to the event's value.
    }
    
    // Add this event to the raid.
    $event_instance = array(
      'event_value_id' => $event_value['event_value_id'],
      'raid_id' => $values['raid_id'],
      'note' => $values['note']
    );
    drupal_write_record('guild_event_instance', $event_instance);
  }
  
  $form_state['redirect'] = 'admin/guild/raids/' . $values['raid_id'] . '/events';
}

/**
 * Theme the raid event editing page.
 *
 * @ingroup themeable
 */
function theme_guild_raid_event_edit($form) {
  drupal_add_css(drupal_get_path('module', 'guild') . '/guild.css');
  
  $output = '<p>';
  $output .= '<strong>' . drupal_render($form['raid_name']) . '</strong>';
  $output .= '<br />' . drupal_render($form['raid_date']);
  $output .= empty($form['raid_comment']['#value']) ? '' : '<br />' . drupal_render($form['raid_comment']);
  $output .= '</p>';
  
  if (isset($form['name']) && is_array($form['name'])) {
    foreach (element_children($form['name']) as $key) {
      $name = drupal_render($form['name'][$key]);
      if (!empty($form['description'][$key]['#value'])) {
        $name .= '<div class="guild-description">' . drupal_render($form['description'][$key]) . "</div>\n";
      }
      
      $row = array();
      $row[] = drupal_render($form['events'][$key]);
      $row[] = $name;
      $row[] = drupal_render($form['note'][$key]);
      $row[] = drupal_render($form['amount'][$key]);
      
      $rows[] = $row;
    }
  }
  else {
    $t_args =  array('@add-events' => url('admin/guild/events/add', array('query' => drupal_get_destination())));
    $rows[] = array(array(
      'data' => t('No events available. You can create more at the <a href="@add-events">Guild management > Events</a> page.', $t_args),
      'colspan' => '4',
      'align' => 'center'
    ));
  }
  
  $output .= theme('table', $form['header']['#value'], $rows);
  if ($form['pager']['#value']) {
    $output .= drupal_render($form['pager']);
  }

  $output .= drupal_render($form);

  return $output;
}

function guild_raid_remove_event_confirm(&$form_state, $raid, $event_instance_id = NULL) {
  dpm($event_instance_id);  // Reminder: This id may not be valid.
  
  $form['notice'] = array(
    '#value' => t('All members and the following items will be removed.')
  );
  
  $form['child_events'] = array(
    '#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE
  );
  
  $form['child_events']['not_implemented'] = array(
    '#type' => 'hidden',
    '#prefix' => '<li>',
    '#suffix' => '<span style="color: red;">' . t('Not implemented.') . '</span></li>'
  );
  
  return confirm_form($form, t('Remove event from raid'), 'admin/guild/raids/' . $raid['raid_id'] . '/events',
    t('This action cannot be undone.'), t('Remove event'), t('Cancel'));
}

function guild_raid_remove_event_confirm_submit($form, &$form_state) {
  // @todo Implement removing events from a raid.
  
  return;
}

/**
 * Creates a grid of checkboxes to add and remove guild members from raid events.
 *
 * @param array $form_state
 * @param array $raid
 */
function guild_raid_members($form_state, $raid = NULL) {
  if (empty($raid)) {
    return drupal_not_found();
  }
  
  $form['raid_id'] = array('#type' => 'value', '#value' => $raid['raid_id']);
  
  // 
  $result = db_query(
    "SELECT ei.event_instance_id AS id, et.name, t.nid " .
    "FROM {guild_event_instance} ei " .
    "INNER JOIN {guild_event_value} ev USING(event_value_id) " .
    "INNER JOIN {guild_event_template} et USING(event_template_id) ".
    "LEFT JOIN {guild_transaction} t USING(event_instance_id) " .
    "WHERE raid_id = %d ORDER BY et.name ASC",
    $raid['raid_id']
  );
  
  $events = array();
  while ($event = db_fetch_object($result)) {
    $events[$event->id] = $event->name;
    
    if (isset($event->nid)) {
      $checked[$event->id][] = $event->nid;
    }
  }
  
  if (empty($events)) {
    drupal_set_message(t('You cannot assign members to a raid with no events.'), 'error');
    drupal_goto('admin/guild/raids');
  }
  
  // 
  $result = db_query(db_rewrite_sql(
    "SELECT m.nid, n.title, m.status FROM {guild_member} m " .
    "INNER JOIN {node} n USING(nid) " .
    "WHERE m.status <> %d ORDER BY n.title ASC"
  ), GUILD_PLAYER_HIDDEN);
  
  $members = array();
  while ($member = db_fetch_object($result)) {
    $options[$member->nid] = '';
    
    $status = ($member->status == GUILD_PLAYER_ACTIVE) ? 'active' : 'inactive';
    $members[$status][$member->nid] = array('#value' => check_plain($member->title));
  }
  
  // Build the form rows.
  $form['members'] =
    array('active' => array('#value' => t('Active members (!count)', array('!count' => count($members['active']))))) +
    (isset($members['active']) ? $members['active'] : array()) +
    array('inactive' => array('#value' => t('Inactive members (!count)', array('!count' => count($members['inactive']))))) +
    (isset($members['inactive']) ? $members['inactive'] : array());
  
  // Build the form columns.
  foreach ($events as $event_id => $event_name) {
    $form['event_names'][$event_id] = array('#value' => $event_name, '#tree' => TRUE);
    $form['checkboxes'][$event_id] = array(
      '#type' => 'checkboxes',
      '#options' => $options,
      '#default_value' => isset($checked[$event_id]) ? $checked[$event_id] : array()
    );
  }
  
  $form['submit'] = array('#type' => 'submit', '#value' => t('Save members'));
  
  return $form;
}

/**
 * Form submission handler for guild_raid_members().
 */
function guild_raid_members_submit($form, &$form_state) {
  dpm($form_state['values']);
  //
  foreach ($form_state['values'] as $event_id => $member_ids) {
    // We only want the checkbox information.
    if (is_numeric($event_id)) {
      // Start fresh; delete all existing transactions for this event instance.
      db_query("DELETE FROM {guild_transaction} WHERE event_instance_id = %d", $event_id);
      
      $args = array();
      $member_ids = array_filter($member_ids);
      
      // Add any selected event participants.
      if (!empty($member_ids)) {
        foreach ($member_ids as $nid) {
          $args[] = $nid;
          $args[] = $event_id;
        }
        
        $placeholders = '(%d, %d)' . str_repeat(',(%d, %d)', count($member_ids) - 1);   // Really?
        db_query("INSERT INTO {guild_transaction} (nid, event_instance_id) VALUES $placeholders", $args);
      }
    }
  }
  
  drupal_set_message(t('The changes have been saved.'));
  
  // @todo If a member was inactive, but got added to an event, update their status.
  //cache_clear_all();
}

/**
 * Theme the raid member selector.
 *
 * @ingroup themeable
 */
function theme_guild_raid_members($form) {
  foreach (element_children($form['members']) as $key) {
    $row = array();   // Yep. Not initializing this causes quite a few errors.
    
    if (is_numeric($key)) {
      // @todo Proof of concept. Move into JS later.
      $select_all_events = '<div class="guild-split-cell-ralign" title="' . t('Select all events for this member') . '">&raquo;</div>';
      
      // @todo Implement the JS to select all the checkboxes in a row. See misc/tableselect.js for more.
      $row[] = array(
        'data' => drupal_render($form['members'][$key]) . $select_all_events,
        'class' => 'guild-select-all-events'
      );
      
      foreach (element_children($form['checkboxes']) as $event_id) {
        // @todo Add title attribute with "member name : event name".
        $row[] = array('data' => drupal_render($form['checkboxes'][$event_id][$key]), 'class' => 'checkbox');
      }
    }
    else {
      $row[] = array(
        'data' => drupal_render($form['members'][$key]),
        'class' => 'category',
        'colspan' => count(element_children($form['event_names'])) + 1
      );
    }
    
    $rows[] = $row;
  }
  
  // @todo Move style code into a CSS file.
  $header = array(array('data' => '', 'style' => 'width: 20%;'));
  foreach (element_children($form['event_names']) as $event_id) {
    $header[] = array('data' => drupal_render($form['event_names'][$event_id]), 'class' => 'checkbox', 'style' => 'max-width: 50px;');
  }
  
  $output = theme('table', $header, $rows); //, array('id' => 'raid-members'));
  $output .= drupal_render($form);
  
  return $output;
}

/**
 *
 *
 * @see guild_delete_event(), guild_delete_item()
 */
function guild_delete_raid($raid) {
  if (!is_object($raid) || !is_numeric($raid->raid_id)) {
    watchdog('guild', 'Cannot delete a non-existant raid.', array(), WATCHDOG_WARNING);
    return;
  }
  
  // Delete the raid.
  db_query('DELETE FROM {guild_raid} WHERE raid_id = %d', $raid->raid_id);
  watchdog('guild', 'raid: deleted raid %name.', array('%name' => $raid->name));
  
  // @todo Update other tables when a raid is about to be deleted.
}

/**
 * @todo Experimental function: _guild_admin_title().
 *   Not tested. Not used.
 *   Move to alternate file.
 */
function _guild_admin_title($type, $entry) {
  if (!isset($entry)) {
    return NULL;
  }
  
  if (is_object($entry)) {
    $entry = (array)$entry;
  }
  
  //$format = variable_get('date_format_short', 'm/d/Y - H:i');
  //$sort = array();
  //$sort['day'] = max(strpos($format, 'd'), strpos($format, 'j'));
  //$sort['month'] = max(strpos($format, 'm'), strpos($format, 'M'));
  //$sort['year'] = strpos($format, 'Y');
  //asort($sort);
  //$order = array_keys($sort);
  
  switch ($type) {
    case 'events':
    case 'items':
      return $entry['name'];
    case 'raids':
      return t('@name on @date', array(
        '@name' => $entry['name'], '@date' => format_date($entry['timestamp'], 'custom', 'F j, Y', 0)
      ));
    case 'standings':
      return $entry['title'];
    default:
      return NULL;
  }
}
